package com.dcdata.xian.utils;

import com.dcdata.xian.pojo.GjznCard;
import com.dcdata.xian.pojo.GjznRoute;
import com.dcdata.xian.pojo.GjznStation;
import lombok.extern.java.Log;

import java.lang.reflect.Field;
import java.util.Date;

/**
 * @author: xinmi
 * @date: 2020/10/30
 * @description:
 */
@Log
public class BeanUtil {

    /**
     * @param l1 GjznRoute 1
     * @param l2 GjznRoute 2
     * @return if 2 GjznCard data is same return true, otherwise return false
     * @throws IllegalAccessException catch illegal access exception
     */
    public static boolean routeDataSameCheck(GjznRoute l1, GjznRoute l2) throws IllegalAccessException {

        Field[] fields = GjznRoute.class.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);

            if (fieldDiffCheck(field, l1, l2)) {
                return false;
            }
        }

        return true;

    }

    /**
     * @param l1 GjznStation 1
     * @param l2 GjznStation 2
     * @return if 2 GjznCard data is same return true, otherwise return false
     * @throws IllegalAccessException catch illegal access exception
     */
    public static boolean stationDataSameCheck(GjznStation l1, GjznStation l2) throws IllegalAccessException {

        Field[] fields = GjznStation.class.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);

            if (fieldDiffCheck(field, l1, l2)) {
                return false;
            }
        }

        return true;

    }

    /**
     * @param l1 GjznCard 1
     * @param l2 GjznCard 2
     * @return if 2 GjznCard data is same return true, otherwise return false
     * @throws IllegalAccessException catch illegal access exception
     */
    public static boolean cardDataSameCheck(GjznCard l1, GjznCard l2) throws IllegalAccessException {

        Field[] fields = GjznCard.class.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);

            if (fieldDiffCheck(field, l1, l2)) {
                return false;
            }
        }

        return true;

    }

    /**
     * @param field field to be checked
     * @param left  left item
     * @param right right item
     * @return 2 item different true, same false
     * @throws IllegalAccessException catch illegal access exception
     */
    public static <T> boolean fieldDiffCheck(Field field, T left, T right) throws IllegalAccessException {

        if (!field.getName().equals("serialVersionUID") && !field.getName().equals("id") ) {
            if ( left == null && right == null) {
                return false;
            } else if (left == null && right != null){
                if( field.get(right) == null ){
                    return false;
                } else {
                    return true;
                }
            } else if (left != null && right == null){
                if( field.get(left) == null ){
                    return false;
                } else {
                    return true;
                }
            }

            if (field.get(left) != null && field.get(right) != null) {
                if (!field.get(left).equals(field.get(right))) {
                    //log.info(field.get(left) + " != " + field.get(right));
                    return true;
                }
            } else if (field.get(left) != null && field.get(right) == null) {
                return rightNullDiffCheck(field, left);
            } else if (field.get(left) == null && field.get(right) != null) {
                return leftNullDiffCheck(field, right);
            }
        }
        return false;
    }

    /**
     * @param field field to be checked
     * @param right right item
     * @return if right item is default mean same, no default mean different.
     * @throws IllegalAccessException catch illegal access exception
     */
    public static <T> boolean leftNullDiffCheck(Field field, T right) throws IllegalAccessException {
        if (field.getType().isAssignableFrom(String.class)) {
            if (field.get(right) != "") {
                log.info("field.get(left) == null field.get(right) " + field.get(right));
                return true;
            }
        } else if (field.getType().isAssignableFrom(Long.class)) {
            if ((long) field.get(right) != 0L) {
                log.info("field.get(right) = " + field.get(right) + " field.get(left) == null");
                return true;
            }
        } else if (field.getType().isAssignableFrom(Date.class)) {
            if (field.get(right) != null) {
                log.info("field.get(right) = " + field.get(right) + " field.get(left) == null");
                return true;
            }
        } else {
            if ((int) field.get(right) != 0) {
                log.info("field.get(right) = " + field.get(right) + " field.get(left) == null");
                return true;
            }
        }

        return false;
    }

    /**
     * @param field field to be checked
     * @param left  left item
     * @return if left item is default mean same, no default mean different.
     * @throws IllegalAccessException catch illegal access exception
     */
    public static <T> boolean rightNullDiffCheck(Field field, T left) throws IllegalAccessException {

        if (field.getType().isAssignableFrom(String.class)) {
            if (field.get(left) != "") {
                log.info("field.get(left) = " + field.get(left) + " field.get(right) == null");
                return true;
            }
        } else if (field.getType().isAssignableFrom(Long.class)) {
            if ((long) field.get(left) != 0L) {
                log.info("field.get(left) = " + field.get(left) + " field.get(right) == null");
                return true;
            }
        } else if (field.getType().isAssignableFrom(Date.class)) {
            if (field.get(left) != null) {
                log.info("field.get(left) = " + field.get(left) + " field.get(right) == null");
                return true;
            }
        } else {
            if ((int) field.get(left) != 0) {
                log.info("field.get(l1) = " + field.get(left) + " field.get(right) == null");
                return true;
            }
        }

        return false;
    }
}
